/*******************************************************************************
 * FilePath    : /Src/BSP/UART.c
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-04-03 15:06:14
 * LastEditors : AndrewHu
 * LastEditTime: 2022-02-16 17:07:17
 * Description :
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define MAX_SIZE 250
#define AT_CMD_MAX 100 // AT指令长度不能超过100
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u32 BaudRate = BaudRate_Def;
static u8 txBuf[MAX_SIZE], rxBuf[MAX_SIZE];
static u8 txIn = 0, rxIn = 0;   //待发送、接收待取出数据的Index
static u8 txOut = 0, rxOut = 0; //已发送、接收并取出数据的Index
static u8 rxTimeOut = 0;        //接收超时，判断串口数据是否发送完成
static u8 txEn = 0;             //发送使能标志
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/

/*******************************************************************************
 * Function    : GetBaudRate
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:06:41
 * Description :
 ******************************************************************************/
u32 GetBaudRate(void)
{
    return BaudRate;
}
/*******************************************************************************
 * Function    : SetBaudRate
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2021-05-08 19:36:55
 * Description :
 ******************************************************************************/
void SetBaudRate(u32 rate)
{
    BaudRate = rate;
}
/*******************************************************************************
 * Function   : UartRx_Int
 * Parameter  : void
 * Returns    : void
 * Description:
 * Note:      :
 *******************************************************************************/
void UartRx_Int(void)
{
    AHL_Data_ArryIn(rxBuf, MAX_SIZE, &rxIn, UART_ReceiveData(UART1));
    rxTimeOut = 0x00; //倒计时，判断串口数据是否接收完
}
/*******************************************************************************
 * Function   : UartTx_Int
 * Parameter  : void
 * Returns    : void
 * Description:
 * Note:      :
 *******************************************************************************/
void UartTx_Int(void)
{ //还有数据未发完
    if (txIn != txOut)
    {
        UART_SendData(UART1, AHL_Data_ArryOut(txBuf, MAX_SIZE, &txOut));
    }
    else
    { //数据发送完成
        txEn = 0x00;
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Byte
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 18:28:52
 * Description : 串口发送一个字节
 ******************************************************************************/
void Uart_Send_Byte(u8 data)
{
    AHL_Data_ArryIn(txBuf, MAX_SIZE, &txIn, data);
}
/*******************************************************************************
 * Function    : Uart_Send_String
 * Brief       :
 * Parameter   : {u8*} data-字符串或数组
 * Returns     : {u8} len-长度
 * Date        : 2020-03-24 18:48:47
 * Description : 发送一个字符串或数组
 ******************************************************************************/
void Uart_Send_String(u8 *data, u8 len)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        AHL_Data_ArryIn(txBuf, MAX_SIZE, &txIn, *data);
        data++;
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Byte2Ascii
 * Brief       :
 * Parameter   : {u8} data-待发送数据
 * Returns     :
 * Date        : 2020-03-24 18:30:09
 * Description : 串口发送一个字节（转换成ASCII）
 ******************************************************************************/
void Uart_Send_Byte2Ascii(u8 data)
{
    Uart_Send_Byte(AHL_Data_Hex2Ascii_4bit(data >> 4));
    Uart_Send_Byte(AHL_Data_Hex2Ascii_4bit(data));
}
/*******************************************************************************
 * Function    : Uart_Send_Array
 * Brief       :
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Returns     :
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（原始数据）
 ******************************************************************************/
void Uart_Send_Array(u8 *data, u8 len)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        Uart_Send_Byte(data[i]);
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array_R
 * Brief       :
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Returns     :
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（原始数据），倒序
 ******************************************************************************/
void Uart_Send_Array_R(u8 *data, u8 len)
{
    u8 i;
    for (i = len; i != 0; i--)
    {
        Uart_Send_Byte(data[i - 1]);
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array2Ascii
 * Brief       :
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Parameter   : {u8} space-是否空格做间隔
 * Returns     :
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（转成ASCII）
 ******************************************************************************/
void Uart_Send_Array2Ascii(u8 *data, u8 len, u8 space)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        Uart_Send_Byte2Ascii(data[i]);
        if (space)
            Uart_Send_Byte(' '); //插入空格
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array2Ascii_R
 * Brief       :
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-待发送数组长度
 * Parameter   : {u8} space-是否空格做间隔
 * Returns     :
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（转成ASCII），倒序
 ******************************************************************************/
void Uart_Send_Array2Ascii_R(u8 *data, u8 len, u8 space)
{
    u8 i;
    for (i = len; i != 0; i--)
    {
        Uart_Send_Byte2Ascii(data[i - 1]);
        if (space)
            Uart_Send_Byte(' '); //插入空格
    }
}
/*******************************************************************************
 * Function    : GetUartTxFlag
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 15:16:44
 * Description : 获取串口发送状态
 ******************************************************************************/
u8 GetUartTxFlag(void)
{
    return txEn;
}
/*******************************************************************************
 * Function    : GetUartStatus
 * Brief       : 获取串口工作状态
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 15:16:44
 * Description :
 ******************************************************************************/
u8 GetUartStatus(void)
{
    if ((txEn != 0) || (txOut != txIn) || (rxOut != rxIn))
        return 1; //串口有数据待处理
    else
        return 0; //串口空闲
}
/*******************************************************************************
 * Function    : BleSendData
 * Brief       :
 * Parameter   : {u8} overflag-串口数据是否接收完成
 * Returns     :
 * Date        : 2020-03-23 17:36:40
 * Description : 从串口接受数组中取出数据给蓝牙发送
 ******************************************************************************/
static void BleSendData(u8 overflag)
{
    u8 i = 0;
    u8 bleUartData[20] = {0};

    if (overflag == 0)
    {
        //数据尚未接收完
        if (rxIn >= rxOut)
        {
            if ((rxIn - rxOut) < 20)
                return; //没有达到20个字节
        }
        else
        {
            if ((MAX_SIZE - rxOut + rxIn) < 20)
                return; //没有达到20个字节
        }
    }
    //达到了20个字节，或接收完成
    while (rxIn != rxOut) //有待取出数据
    {
        bleUartData[i] = AHL_Data_ArryOut(rxBuf, MAX_SIZE, &rxOut);

        i++;
        if (i >= 20)
            break; //数据长度超过20，只发送20个字节
    }

    if (GetConnectedStatus())
    {
        SendNotifyData(bleUartData, i);
        // Printf_OK();
    }
    else
    {
        //蓝牙未连接
        Printf_ConnectStatus(0);
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Data
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 19:02:59
 * Description : 串口数据发送判断
 ******************************************************************************/
void Uart_Send_Data(void)
{
    if ((txOut != txIn) && (txEn == 0))
    { //有数据待发送，发送使能标志未置1
        // Exit2Uart();
        txEn = 1;
        UART_ITConfig(UART1, UART_IT_TXIEN, ENABLE);
        UART_SendData(UART1, AHL_Data_ArryOut(txBuf, MAX_SIZE, &txOut));
    }
}
/*******************************************************************************
 * Function    : Uart_Receive_Data
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 19:01:52
 * Description : 接收数据
 ******************************************************************************/
void Uart_Receive_Data(void)
{
    if (rxOut == rxIn)
    {
        rxTimeOut = 0x00;
        return; //没有接收到数据
    }

    if (rxTimeOut < 0x02)
    { //串口正在接收数据

        //串口有数据时会一直清零
        rxTimeOut++;
        BleSendData(0);
    }
    else
    {
        //串口数据接收完成，取出数据
        BleSendData(1);
        rxTimeOut = 0x00;
    }
}
/*******************************************************************************
 * Function    : Fun_Uart_Run
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 19:02:19
 * Description : 串口执行
 ******************************************************************************/
void Fun_Uart_Run(void)
{
    Uart_Send_Data();
    Uart_Receive_Data();
}
